package view; 

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.Map;

import main.Log;
import model.Model;

public class ListOverlay extends Overlay{
	private List<Model> modelsList;
	private int iconsPerPage;
	private int iconHeight;
	private int iconWidth;
	private int iconSpacing;
	private int centerX;
	private int centerY;
	private ListProvider provider;
	private int listLocation;
	//TODO how to get screen width and height of window this spawns from
	
	/**
	 * @param size The outer dimension of the gamewindow
	 * @param provider the ListProvider that will provide information to this ListOverlay
	 * @param iconsPerPage the iconsPerPage to display on view
	 * @param centerX the centeredX and centeredY location for all items (this not an upper left corner)
	 * @param centerY see above
	 */
	public ListOverlay(Dimension size, ListProvider provider, int iconsPerPage, int centerX, int centerY) {
		super(size);
		this.provider = provider;
		provider.subscribe(this);
		this.iconsPerPage = iconsPerPage;
		iconWidth = 50;
		iconHeight = 50;
		iconSpacing = 20;
		this.centerX = centerX;
		this.centerY = centerY;
		this.listLocation = 0;
	}
	/**
	 * @param size The outer dimension of the gamewindow
	 * @param provider the ListProvider that will provide information to this ListOverlay
	 * @param iconsPerPage the iconsPerPage to display on view
	 * @param centerX the centeredX and centeredY location for all items (this not an upper left corner)
	 * @param centerY see above
	 * @param iconWidth  the iconWidth of each image 
	 * @param iconHeight the iconHeight of each image
	 * @param iconSpacing the spacing between items to display
	 */
	public ListOverlay(Dimension size, ListProvider provider, int iconsPerPage, int centerX, int centerY, int iconWidth, int iconHeight, int iconSpacing) {
		super(size);
		this.provider = provider;
		provider.subscribe(this);
		this.iconsPerPage = iconsPerPage;
		this.iconWidth = iconWidth;
		this.iconSpacing = iconSpacing;
		this.centerX = centerX;
		this.centerY = centerY;
		this.listLocation = 0;
	}
	/**
	 * The method that updates this list when any subscribed ListProvider changes
	 * @param lp The ListProvider updating this ListOverlay
	 */
	public void updateList(ListProvider lp) {
		super.removeAllButtons();
		modelsList = null;
		modelsList = lp.getModelsList();
		Map<Model, MouseListener> listenerMap = lp.getListenersMap();
		int i = 0;
		int iterListOffset = 0;
		int xOff = iconWidth+iconSpacing;
		int upperLeftY;
		int upperLeftX;
		if (iconsPerPage%2 == 1) {
			//odd iconsPerPage therefore draw ListOverlay with one centered GameButton
			upperLeftY = centerY-iconWidth/2;
			upperLeftX = centerX-(iconsPerPage/2)*iconWidth - iconSpacing*(iconsPerPage-1)/2 - iconWidth/2;
		}
		else {
			//even iconsPerPage therefore draw ListOverlay with center between two centered buttons
			upperLeftY = centerY-iconWidth/2;
			upperLeftX = centerX-(iconsPerPage/2)*iconWidth - iconSpacing*(iconsPerPage-1)/2;// + iconSpacing/2;
		}
		if (upperLeftX < 0|| upperLeftY < 0) {
			Log.out(Log.VIEW, "{ERROR} The List Overlay is out of bounds!");
			Log.out(Log.VIEW, "See " + provider.getClass().getName());
			System.exit(0);
		}
		//TODO HACK fix the arrow image loading
		GameButton LEFT_CLICK = new GameButton("<", new Rectangle(upperLeftX-xOff*3/4, upperLeftY, iconWidth/2, iconHeight), ModelToImage.getImage("ArrowLeft"));
		LEFT_CLICK.attachListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				changeListLocation(true);
			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
		});
		super.addButton(LEFT_CLICK);
		for (Model m : modelsList) {
			if (i >= listLocation && i <= modelsList.size() && iterListOffset < iconsPerPage) { 
				GameButton gb = new GameButton(m.getName(), new Rectangle(upperLeftX+xOff*iterListOffset, upperLeftY, iconWidth, iconHeight), ModelToImage.getImage(m.getName()));
				gb.attachListener(listenerMap.get(m));
				super.addButton(gb);
				iterListOffset++;
			}
			i++;
			if (i > modelsList.size()) break; //(listLocation + iconsPerPage-1)) break;
		}
		//TODO HACK fix the arrow image loading
		GameButton RIGHT_CLICK = new GameButton("<", new Rectangle(upperLeftX+xOff*(iconsPerPage), upperLeftY, iconWidth/2, iconHeight), ModelToImage.getImage("ArrowLeft"));
		RIGHT_CLICK.attachListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				changeListLocation(false);
			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
		});
		super.addButton(RIGHT_CLICK);	}
	protected void drawOverlay(Graphics g) {
		g.setColor(Color.RED);
		//g.fillOval(centerX-5, centerY-5, 10, 10);
		//g.drawLine(centerX, 0, centerX, this.getOuterDimension().height);
		//g.drawLine(0, centerY, this.getOuterDimension().width, centerY);
		updateList(provider);
	}
	public void onResize() {
	}
	@Override
	public void update(Model m) {
		// TODO Auto-generated method stub
	}
	/**
	 * This is for the right and left button clicks of the ListOverlay.  True for moving left, false for moving right.
	 * @param moveLeft Boolean value to choose to move right or left
	 */
	private void changeListLocation(boolean moveLeft) {
		if (moveLeft) {
			Log.out(Log.VIEW, "Move Left through List");
			if (listLocation-iconsPerPage >= 0)
				listLocation = listLocation - iconsPerPage;
			else 
				listLocation = 0;
		}
		else {
			Log.out(Log.VIEW, "Move Right through List");
			if (listLocation+iconsPerPage < this.modelsList.size())
					listLocation = listLocation+iconsPerPage;
		}
		updateList(provider);
	}
	/**
	 * @param iconsPerPage the iconsPerPage to set
	 */
	public void setIconsPerPage(int iconsPerPage) {
		this.iconsPerPage = iconsPerPage;
	}
	/**
	 * @return the iconsPerPage
	 */
	public int getIconsPerPage() {
		return iconsPerPage;
	}
	/**
	 * @param iconWidth the iconWidth to set
	 */
	public void setIconWidth(int iconWidth) {
		this.iconWidth = iconWidth;
	}
	/**
	 * @return the iconWidth
	 */
	public int getIconWidth() {
		return iconWidth;
	}
	/**
	 * @param iconSpacing the iconSpacing to set
	 */
	public void setIconSpacing(int iconSpacing) {
		this.iconSpacing = iconSpacing;
	}
	/**
	 * @return the iconSpacing
	 */
	public int getIconSpacing() {
		return iconSpacing;
	}
	/**
	 * @param centerX the centerX to set
	 */
	public void setCenterX(int centerX) {
		this.centerX = centerX;
	}
	/**
	 * @return the centerX
	 */
	public int getCenterX() {
		return centerX;
	}
	/**
	 * @param centerY the centerY to set
	 */
	public void setCenterY(int centerY) {
		this.centerY = centerY;
	}
	/**
	 * @return the centerY
	 */
	public int getCenterY() {
		return centerY;
	}
	/**
	 * @return the iconHeight
	 */
	public int getIconHeight() {
		return iconHeight;
	}
	/**
	 * @param iconHeight the iconHeight to set
	 */
	public void setIconHeight(int iconHeight) {
		this.iconHeight = iconHeight;
	}
	/**
	 * @return the provider
	 */
	public ListProvider getProvider() {
		return provider;
	}
	/**
	 * @param provider the provider to set
	 */
	public void setProvider(ListProvider provider) {
		this.provider = provider;
	}
}
